var FM_AutoCAD_API = Class.create();
FM_AutoCAD_API.prototype = {
	initialize: function () {
	},
	
	type: 'FM_AutoCAD_API',
	
	createDraftVersion: function(tableRecordID, recordName, tableID){
		
		var result = {
			success: false,
			message: "",
			sys_id: ""
		};
		
		//Get the the active and draft(if exists) records of the record passed
		//Order by status so that we get the active first
		var grCheckedOutVersion = new GlideRecord("x_lsmcb_fm_version");
		grCheckedOutVersion.addQuery("record", tableRecordID);
		//grCheckedOutVersion.addNotNullQuery("checked_out_by");
		grCheckedOutVersion.addQuery("status", "IN", "draft,active");
		grCheckedOutVersion.orderBy("status");
		grCheckedOutVersion.query();
		
		var activeVersionID;
		
		//if we have results
		if(grCheckedOutVersion.next()){
			//check if the row we got has been checkout first, if not return message
			if(!grCheckedOutVersion.checked_out_by){
				result.message = "This file has not been checked out";
			}
			else
			{
				activeVersionID = grCheckedOutVersion.getUniqueValue();

				//in case the current user don't match the user that checked this file we return an error
				if(grCheckedOutVersion.getValue("checked_out_by") != gs.getUserID()){
					result.message = "This file have already been checked ou by: " + grCheckedOutVersion.checked_out_by.getDisplayValue();
				}
				else{
					//if we have more lines we either have more than one active, not likely, or we already have a draft
					if(grCheckedOutVersion.hasNext()){

						//Go to the, hopefully, draft record
						grCheckedOutVersion.next();

						//in the oddly case that we have another active version we have consistency problems, send a error to contact the admin
						if(grCheckedOutVersion.getValue("status") == "active"){
							result.message = "There is more than one active version of this file, please contact your system administrator.";
						}
						else{
							result.message = "We already have the correct draft for this file, no need to create a new one.";
							result.success = true;
							result.sys_id = grCheckedOutVersion.getUniqueValue();

							//Old manual layers must be cleared before duplicating new ones, is case they were edited meanwhile
							var grDeleteManualLayers = new GlideRecord('x_lsmcb_fm_layer');
							grDeleteManualLayers.addQuery('version', result.sys_id);
							grDeleteManualLayers.addQuery('layer_configuration.source', 'manual');
							grDeleteManualLayers.deleteMultiple();
						}
					}
					else{
						//Insert a draft Version using some fields of the active Version
						//Set the status to Draft
						grCheckedOutVersion.setValue("status", "draft");
						//Set the id of the parent to be the active record we copied from
						grCheckedOutVersion.setValue("parent", grCheckedOutVersion.getUniqueValue());

						//grCheckedOutVersion.setValue("version", ""); //Create new version, for later

						//Insert the active record as new with the field changes done previously
						grCheckedOutVersion.insert();

						if(grCheckedOutVersion.isActionAborted())
							{
							result.message = "Operation was aborted";
						}
						else{
							result.message = "The draft was created successfully.";
							result.success = true;
							result.sys_id = grCheckedOutVersion.getUniqueValue();
						}
					}
				}
			}
		}
		else{
			//if there are no active or draft versions, create a new one
			var grInsertVersion = new GlideRecord('x_lsmcb_fm_version');
			grInsertVersion.initialize();
			grInsertVersion.name = recordName;
			grInsertVersion.status = 'draft';
			grInsertVersion.table = tableID;
			grInsertVersion.record = tableRecordID;
			grInsertVersion.checked_out_by = gs.getUserID();
			grInsertVersion.checked_out_date = new GlideDateTime();
			//grInsertLayer.version = "";
			grInsertVersion.insert();
			
			if(grInsertVersion.isActionAborted())
				{
				result.message = "Operation was aborted";
			}
			else{
				result.message = "The draft was created successfully.";
				result.success = true;
				result.sys_id = grInsertVersion.getUniqueValue();
			}
		}
		
		if(result.success && typeof activeVersionID != 'undefined'){
			//Duplicate manual layers
			var grDuplicateManualLayers = new GlideRecord('x_lsmcb_fm_layer');
			grDuplicateManualLayers.addQuery('version', activeVersionID);
			grDuplicateManualLayers.addQuery('active', true);
			grDuplicateManualLayers.addQuery('layer_configuration.source', 'manual');
			grDuplicateManualLayers.query();
			
			while(grDuplicateManualLayers.next()){
				grDuplicateManualLayers.version = result.sys_id;
				grDuplicateManualLayers.insert();
			}
		}
		
		return result;
	},
	
	updateVersion: function(versionID, attachmentID, publish){
		//check if we have a DXF in the table
		var gr = new GlideRecord("sys_attachment");
		gr.addQuery("table_sys_id", versionID);
		gr.addQuery("content_type", "image/vnd.dxf");
		gr.orderByDesc('sys_updated_on');
		gr.setLimit(1);
		gr.query();
		
		//if we dont have a DXF end and return false
		if(!gr.hasNext()){
			return false;
		}
		
		//use the DXF in the attachment to convert to SVG and GeoJSON and save them
		var converter = new FM_DXFConversion();
		gs.info("AM - preconvert");
		if(!converter.convertAndSave(versionID, attachmentID)){
			return false;
		}
		gs.info("AM - posconvert");
		
		//if publish is true, active the current draft version
		if(publish){
			this.activateDraft(versionID);
		}
		
		return true;
	},
	
	activateDraft: function(VersionID){
		var grDraft = new GlideRecord("x_lsmcb_fm_version");
		grDraft.get(VersionID);
		
		grDraft.setValue("status", "active");
		grDraft.setValue("checked_out_by", "NULL");
		grDraft.setValue("checked_out_date", "NULL");
		grDraft.update();
	},
	
	getData: function (fmClass, sys_id) {
		var json = [];
		var gr = new GlideRecord("x_lsmcb_fm_" + fmClass);
		if (sys_id) {
			
			if (fmClass === "room") {
				gr.addQuery("floor", sys_id);
			}
			if (fmClass === "floor") {
				gr.addQuery("building", sys_id);
			}
		}
		
		gr.query();
		while (gr.next()) {
			json.push({
				id: gr.getValue("id"),
				name: gr.getValue("name"),
				sys_id: gr.getValue("sys_id")
			});
		}
		return json;
	},
	
	//Used to retrieve DWG read-only mode
	//Will always return the Active version
	getFloorDWG: function (floor_sys_id) {
		var grVersions = new GlideRecord("x_lsmcb_fm_version");
		grVersions.addQuery("record", floor_sys_id);
		grVersions.addQuery("status", "active");
		grVersions.orderByDesc('status');
		grVersions.setLimit(1);
		grVersions.query();
		
		var versionSysId = "";
		
		if (grVersions.next()) {
			versionSysId =  grVersions.getValue("sys_id");
			return this.getVersionDWG(versionSysId);
		}
		
		return null;
	},
	
	getVersionDWG: function (version_sys_id) {
		var grAttachment = new GlideRecord("sys_attachment");
		grAttachment.addQuery("table_sys_id", version_sys_id);
		grAttachment.addQuery("content_type", "image/vnd.dwg");
		grAttachment.orderByDesc('sys_updated_on');
		grAttachment.setLimit(1);
		grAttachment.query();
		if (grAttachment.next()) {
			return grAttachment.getValue("sys_id");
		}
		return null;
	},
	
	checkoutFloor: function (floor_sys_id) {
		
		var result = {
			success: false,
			message: ""
		};
		
		//Get floor draft or active version
		var grVersions = new GlideRecord("x_lsmcb_fm_version");
		grVersions.addQuery("record", floor_sys_id);
		grVersions.addQuery("status", "IN", "draft,active");
		grVersions.orderByDesc('status');
		grVersions.setLimit(1);
		grVersions.query();
		
		if (grVersions.next()){
			
			//Success is true if the DWG can be retrieved and send success message, else send error message
			
			//Check if version is in draft
			if (grVersions.getValue("status") == "draft") {
				//Check if version is in draft by current user
				if (grVersions.getValue("checked_out_by") == gs.getUserID()) {
					result.message = "Draft file retrieved.";
					result.success = true;
					result.dwg_sys_id = this.getVersionDWG(grVersions.getValue("sys_id"));
				}else{
					result.message = "This floor is already in draft by user " + grVersions.checked_out_by.getDisplayValue() + " since " + grVersions.getValue("checked_out_date")+".";
					result.success = false;
				}
				//Check if version is in active
			}else if(grVersions.getValue("status") == "active"){
				//Check if version.checked_out_by is null or by current user
				if (!grVersions.getValue("checked_out_by") || grVersions.getValue("checked_out_by") == gs.getUserID()) {
					result.message = "Active version checked out.";
					result.success = true;
					result.dwg_sys_id = this.getVersionDWG(grVersions.getValue("sys_id"));
					grVersions.checked_out_by = gs.getUserID();
					grVersions.checked_out_date = new GlideDateTime();
					grVersions.update();
				}else{
					result.message = "This floor is already in draft by user " + grVersions.checked_out_by.getDisplayValue() + " since " + grVersions.getValue("checked_out_date")+".";
					result.success = false;
				}
			}
		}else{
			result.message = "No version found.";
			result.success = false;
		}
		
		return result;
	},
	
	getBuildings: function (){
		return this.getData('building');
	},
	
	getFloors: function(sys_id) {
		return this.getData('floor', sys_id);
	},
	
	getRooms: function(sys_id) {
		return this.getData('room', sys_id);
	}
};